<template>
  <div>
    <el-table :data="tableData" style="width: 100%" border>
      <el-table-column prop="date" label="Date" width="180" resizable>
        <template #default="scope">
          <el-date-picker
            v-model="scope.row.date"
            type="date"
            placeholder="Pick a day"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            class="custom-date-picker"
            @change="handleInputChange(scope.row.key)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="name" label="Name" width="180" resizable>
        <template #default="scope">
          <span>{{ scope.row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="address" label="Address" resizable>
        <template #default="scope">
          <el-input v-model="scope.row.address" @change="handleInputChange(scope.row.key)" />
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="Operations" width="160" resizable>
        <template #default="scope">
          <el-button size="small" @click="insertRow(scope.row.key)">Insert</el-button>
          <el-button size="small" @click="deleteRow(scope.row.key)">Delete</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-button type="primary" @click="addRow">Add Row</el-button>
    <el-button type="success" @click="saveChanges">Save Changes</el-button>
    <el-button type="primary" @click="count++">count is {{ count }}</el-button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { ElTable, ElTableColumn, ElDatePicker, ElInput, ElButton, ElMessage } from "element-plus";

interface TableRow {
  key: number;
  date: string;
  name: string;
  address: string;
}

interface TableRowChange {
  key: number;
}

//使用defineComponent包裹导出对象，可激活类型推导（如props参数类型、setup返回值类型）,推荐作为组件定义的标准方式
//若直接导出组件对象（export default { ... }），TypeScript可能无法正确推断类型，导致模板中属性提示缺失。
//在<script setup>中无需显式调用defineComponent，因其语法糖已隐式处理类型推导。
//若需自定义组件选项（如name、props验证），可通过defineOptions实现

export default defineComponent({
  name: "TestEltable5",
  components: {
    ElTable,
    ElTableColumn,
    ElDatePicker,
    ElInput,
    ElButton,
  },
  setup() {
    const count = ref(0); //lvstone test

    const originalTableData = ref<TableRow[]>([
      {
        key: 1,
        date: "2016-05-03",
        name: "Tom",
        address: "No. 189, Grove St, Los Angeles",
      },
      {
        key: 2,
        date: "2016-05-02",
        name: "John",
        address: "No. 189, Grove St, Los Angeles",
      },
      {
        key: 3,
        date: "2016-05-04",
        name: "Morgan",
        address: "No. 189, Grove St, Los Angeles",
      },
      {
        key: 4,
        date: "2016-05-01",
        name: "Jessy",
        address: "No. 189, Grove St, Los Angeles",
      },
    ]);

    const tableData = ref<TableRow[]>([...originalTableData.value]);

    // 获取当前最大 key
    const getMaxKey = (): number => {
      if (tableData.value.length === 0) return 0;
      return Math.max(...tableData.value.map((row) => row.key));
    };

    // 全局计数器，用于生成唯一的 key
    const globalKeyCounter = ref<number>(getMaxKey());

    // 状态数组，用于记录哪些原始数据行被修改过
    const modifiedRows = ref<TableRowChange[]>([]);

    // 状态数组，用于记录哪些行是新增的
    const addedRows = ref<TableRowChange[]>([]);

    // 状态数组，用于记录哪些行被删除
    const deletedRows = ref<TableRowChange[]>([]);

    const handleInputChange = (key: number): void => {
      // 检查该行是否是新增的
      if (!addedRows.value.some((row) => row.key === key)) {
        // 检查该行是否已经被标记为已修改
        if (!modifiedRows.value.some((row) => row.key === key)) {
          // 检查该行是否在 originalTableData 中存在并且内容不同
          //虽然事件上是onchange，以下检查最好加上，有可能在该行先进行修改，但保存前又改回来了，实际上未修改
          //不加的话onchage是触发的，实际值未改（值未改到后台按原值数据库去update下影响倒也不大）
          /** 
          const originalRow = originalTableData.value.find(row => row.key === key);
          const currentRow = tableData.value.find(row => row.key === key);
          if (originalRow && currentRow) {
            if (
              originalRow.date !== currentRow.date ||
              originalRow.name !== currentRow.name ||
              originalRow.address !== currentRow.address
            ){
              modifiedRows.value.push({ key });
            }
          }
          */

          modifiedRows.value.push({ key });
        }
      }
    };

    const addRow = (): void => {
      // 使用全局计数器生成唯一的 key
      const newKey = ++globalKeyCounter.value;
      const newRow: TableRow = {
        key: newKey,
        date: "",
        name: "",
        address: "",
      };
      tableData.value.push(newRow);
      addedRows.value.push({ key: newKey });
      // 新增行默认不标记为已修改
    };

    const insertRow = (key: number): void => {
      // 使用全局计数器生成唯一的 key
      const newKey = ++globalKeyCounter.value;
      const newRow: TableRow = {
        key: newKey,
        date: "",
        name: "",
        address: "",
      };

      // 找到要插入的位置
      const index = tableData.value.findIndex((row) => row.key === key);
      if (index !== -1) {
        tableData.value.splice(index + 1, 0, newRow);
        addedRows.value.push({ key: newKey });

        // 更新 addedRows 和 deletedRows 的索引
        addedRows.value.sort((a, b) => a.key - b.key);
        deletedRows.value.sort((a, b) => a.key - b.key);
      }
    };

    const deleteRow = (key: number): void => {
      // 删除指定 key 的行
      const rowIndex = tableData.value.findIndex((row) => row.key === key);
      if (rowIndex !== -1) {
        // const rowToDelete: TableRow = tableData.value[rowIndex]; // 存储即将删除的行
        tableData.value.splice(rowIndex, 1);

        // 检查该行是否是新增的
        const addedIndex = addedRows.value.findIndex((row) => row.key === key);
        if (addedIndex !== -1) {
          addedRows.value.splice(addedIndex, 1);
        } else {
          // 如果不是新增的，则标记为已删除
          deletedRows.value.push({ key });
        }

        // 同步删除对应的修改状态
        const modifiedIndex = modifiedRows.value.findIndex((row) => row.key === key);
        if (modifiedIndex !== -1) {
          modifiedRows.value.splice(modifiedIndex, 1);
        }

        // 更新 addedRows 和 deletedRows 的索引
        addedRows.value.sort((a, b) => a.key - b.key);
        deletedRows.value.sort((a, b) => a.key - b.key);
      }
    };

    const saveChanges = (): void => {
      // 验证所有行的 date 字段
      const isValid = tableData.value.every((row) => {
        if (!row.date) {
          ElMessage.error(`Row ${row.key}: Date field is required.`);
          return false;
        }
        const date = new Date(row.date);
        if (isNaN(date.getTime()) || date.getFullYear() < 2000) {
          ElMessage.error(`Row ${row.key}: Date must be after January 1, 2000.`);
          return false;
        }
        return true;
      });

      if (!isValid) {
        return; // 如果验证失败，阻止保存操作
      }

      // 过滤出修改过的行
      const modifiedChanges = modifiedRows.value
        .map((row) => tableData.value.find((dataRow) => dataRow.key === row.key))
        .filter((row): row is TableRow => !!row); // 类型断言，确保非空
      //console.log("Modified Changes to save:", modifiedChanges);

      // 获取新增的行
      const newAddedRows = addedRows.value
        .map((row) => tableData.value.find((dataRow) => dataRow.key === row.key))
        .filter((row): row is TableRow => !!row); // 类型断言，确保非空
      //console.log("New Added Rows to save:", newAddedRows);

      // 获取删除的行
      const removedRows = deletedRows.value
        .map((row) => originalTableData.value.find((dataRow) => dataRow.key === row.key))
        .filter((row): row is TableRow => !!row); // 类型断言，确保非空
      //console.log("Deleted Rows to remove:", removedRows);

      // 获取未更改的行
      // function hasId(array: TableRow[], key: number): boolean {
      //   return array.some((item) => item.key === key);
      // }
      // const unchagedRows = originalTableData.value.filter(
      //   (item) => !hasId(newAddedRows, item.key) && !hasId(modifiedChanges, item.key)
      // );
      // console.log("unChange Rows to remove:", unchagedRows);

      // 在这里可以调用 API 将数据发送到服务器
      // 例如：
      // api.saveChanges({ modified: modifiedChanges, added: newAddedRows, deleted: removedRows })
      //   .then(response => {
      //     console.log('Saved successfully:', response);
      //   })
      //   .catch(error => {
      //     console.error('Error saving changes:', error);
      //   });

      //修改后当前的数据
      //tableData.value = [...unchagedRows, ...modifiedChanges, ...newAddedRows];//已经是了，操作时已记录了不用取了

      ElMessage.success("Changes saved successfully.");
    };

    return {
      count,
      tableData,
      saveChanges,
      handleInputChange,
      addRow,
      insertRow,
      deleteRow,
      modifiedRows,
      addedRows,
      deletedRows,
      originalTableData,
    };
  },
});
</script>

<!-- <style>
/* 自定义 el-date-picker 的宽度 */
.custom-date-picker {
  width: 100% !important; /* 确保宽度为 100% */
}

/* 显示表格竖线 */
.el-table--border th.el-table__cell:not(.is-hidden),
.el-table--group::after,
.el-table::before {
  background-color: #ebeef5;
}
</style> -->

<style>
/* 自定义 el-date-picker 的宽度 */
.custom-date-picker {
  width: 100% !important; /* 确保宽度为 100% */
}

/* 显示表格竖线 */
.el-table--border td,
.el-table--border th.is-leaf {
  border-right: 1px solid #ebeef5;
}

/* 修改表格行高 */
.el-table__row {
  height: 25px; /* 调整为你想要的行高 */
}
</style>
